home *** CD-ROM | disk | FTP | other *** search
- /***
- *debug.c - heap checking
- *
- *Copyright (c) 1993-1994, Gregg Jennings. All wrongs reserved.
- * P O Box 200, Falmouth, MA 02541-0200
- *
- *Purpose:
- * Debugging support for DISKED.C.
- *
- *Notice:
- * This progam may be freely used and distributed. Any distrubution
- * with modifications must retain the above copyright statement and
- * modifications noted.
- * No pulp-publication, in whole or in part, permitted without
- * permission (magazines or books).
- *******************************************************************************/
-
- /*
- Versions
-
- 2.1 13-Jan-1994 "alloc.h"
- 2.0 28-Nov-1993
- */
-
- #include <stdio.h>
- #include <conio.h>
- #include <dos.h>
- #include <malloc.h>
-
- #include "mylib.h" /* print and cursor routines */
- #include "alloc.h"
-
- /*********** EXTERNAL DATA ***********/
-
- extern unsigned int blocks; /* alloc() free() calls */
- extern unsigned int nblocks;
- extern unsigned int frees;
- extern unsigned int nfrees;
-
- extern char *heapstat(int status);
-
- /********** INTERNAL DATA ***********/
-
- static int list = 1;
- static char *list_types[]={"","ascii","byte","word","dword"};
-
- static void list_memory(int type);
- void heapdump(int );
-
- void debug(void)
- {
- int c;
-
- for (;;)
- {
- print("\n(debug)*");
- c=conin()&0xff;
- if (c=='h')
- {
- print(" Heap status:");
- printf("\n\n\tStack available %u",stackavail());
- #ifdef _MSC_VER
- printf(", near heap %u",_memavl());
- printf(" (largest block %u).",_memmax());
- #endif
- printf("\n\tAlloc calls %d:%d, Free calls %d:%d.",blocks,nblocks,frees,nfrees);
- heapdump(0);
- }
- else if (c=='d')
- {
- print(" Heap dump:");
- heapdump(1);
- }
- else if (c=='k')
- {
- list++;
- if (list==5)
- list=1;
- printf(list_types[list]);
- list_memory(list);
- }
- else if (c=='l')
- list_memory(0);
- else if (c=='.' || c==0x1b)
- break;
- else if (c=='/' || c=='?')
- {
- print(" Debug Commands:\n\n");
- print(" 'h' heap status\n");
- print(" 'd' heap dump\n");
- print(" 'ln:n' list memory\n");
- print(" 'k' change list format\n");
- }
- }
- }
-
- /*
- display heap
-
- This is from the Microsoft online help database with slight
- modifications.
- */
-
- void heapdump(int stat)
- {
- struct _heapinfo hi;
- int heapstatus;
- register size_t i;
- register char _far *p;
- int uf,un,ff,fn;
-
- printf("\n");
- uf = un = ff = fn = 0;
- hi._pentry = NULL;
- if (stat)
- printf("\nFar Heap:");
-
- while ((heapstatus = _heapwalk( &hi )) == _HEAPOK)
- {
- if (stat)
- printf( "\n\t%s block at %Fp of size %u\t",
- hi._useflag == _USEDENTRY ? "USED" : "FREE",
- hi._pentry,
- hi._size );
-
- if (hi._useflag == _FREEENTRY)
- {
- ++ff;
- if (stat)
- for (p = (char _far *)hi._pentry, i = 0; i < hi._size; p++,i++)
- if ((char)*p != (char)254)
- {
- printf(" overwrite at %Fp (%02X)",p,(char)*p);
- break;
- }
- }
- else
- ++uf;
- }
- if (stat)
- printf("\n\tStatus: %s",heapstat(heapstatus));
-
- hi._pentry = NULL;
- if (stat)
- printf("\nNear Heap:");
- while ((heapstatus = _nheapwalk( &hi )) == _HEAPOK)
- {
- if (stat)
- printf( "\n\t%s block at %Fp of size %u\t",
- hi._useflag == _USEDENTRY ? "USED" : "FREE",
- hi._pentry,
- hi._size );
-
- if (hi._useflag == _FREEENTRY)
- {
- ++fn;
- if (stat)
- for (p = (char _far *)hi._pentry, i = 0; i < hi._size; p++,i++)
- if ((char)*p != (char)254)
- {
- printf(" overwrite at %Fp (%02X)",p,(char)*p);
- break;
- }
- }
- else
- ++un;
- }
- if (stat)
- printf("\n\tStatus: %s\n",heapstat(heapstatus));
- if (!stat)
- printf("\tUsed blocks %d:%d, Free blocks %d:%d.\n",uf,un,ff,fn);
- }
-
- #ifdef _MSC_VER
- #pragma check_pointer(off)
- #endif
-
- /* dump memory, call with 0 to "set" format */
-
- static void list_memory(int type)
- {
- int i,j;
- static byte _far *cp;
- static word _far *ip;
- static dword _far *lp;
- static int size = 1;
- char inbuf[20];
-
- if (type)
- {
- size=type;
- return;
- }
- conout('l');
- if ((i = getstr(inbuf,9,_PUNCT)) > 0)
- {
- i = j = 0;
- sscanf(inbuf,"%x:%x",&i,&j);
- cp = (byte _far *) ((((long)i)<<16) + (long)j);
- ip = (word _far *) ((((long)i)<<16) + (long)j);
- lp = (dword _far *) ((((long)i)<<16) + (long)j);
- }
- else if (i == ABORT)
- return;
- send('\n');
- for (i=0;i<8;i++)
- {
- if (size==1)
- {
- printf("\n%Fp ",cp);
- for (j=0;j<80-21;j++)
- {
- if (*cp == 0 || *cp == 255)
- charout('.');
- else
- charout(*cp);
- cp++;
- curright();
- }
- }
- else if (size==2)
- {
- printf("\n%Fp ",cp);
- for (j=0;j<20;j++)
- {
- pnlz((int)*cp++,2,16);
- curright();
- }
- }
- else if (size==3)
- {
- printf("\n%Fp ",ip);
- for (j=0;j<12;j++)
- {
- pnlz(*ip++,4,16);
- curright();
- }
- }
- else if (size==4)
- {
- printf("\n%Fp ",lp);
- for (j=0;j<6;j++)
- {
- pnlz((int)((*lp)>>16),4,16);
- conout(':');
- pnlz((int)*lp++,4,16);
- curright();
- }
- }
- }
- if (size == 1 || size == 2)
- {
- ip = (word _far *)cp;
- lp = (dword _far *)cp;
- }
- else if (size == 3)
- {
- cp = (byte _far *)ip;
- lp = (dword _far *)ip;
- }
- else if (size == 4)
- {
- ip = (word _far *)lp;
- cp = (byte _far *)lp;
- }
- send('\n');
- }
-